package com.googlecode.archimedes.filegen.controller.implementation;

import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.googlecode.archimedes.filegen.controller.ArchimedesController;
import com.googlecode.archimedes.filegen.controller.GenerationBridge;
import com.googlecode.archimedes.filegen.controller.GenerationException;
import com.googlecode.archimedes.filegen.generator.AbstractGenerator;
import com.googlecode.archimedes.filegen.template.Template;

/**
 * Handles the mechanics of generating source code using Archimedes. This class accepts a GenerationBridge and then extracts the templates and other
 * GenerationBridge assets and executes the templates against the appropriate Generatorable classes as defined by the run-time configuration.
 * 
 * @author Erik Gustavson
 * @version $Id: BasicController.java 1983 2006-01-30 21:18:21 +0000 (Mon, 30 Jan 2006) erik $ Created on Oct 27, 2003
 */
public class BasicController implements ArchimedesController {

	private Log	logger	= LogFactory.getLog(this.getClass().getName());

	/**
	 * Document me!
	 */
	public BasicController() {
		super();
	}

	/**
	 * Handles generation of the source code. The GenerationBridge represents all of templates and assets that are necessary to create a full set of
	 * ArchimedesCode.
	 * 
	 * @param bridge
	 *            The GenerationBridge instance that contains assets and templates that need to be generated.
	 */
	public void generate(GenerationBridge bridge) throws GenerationException {
		try {
			Template template = null;
			AbstractGenerator generator = null;

			// Iterate over the list of templates and look for ones that match our Asset type.
			Iterator iterator = bridge.getTemplates().iterator();
			while (iterator.hasNext()) {
				template = (Template) iterator.next();

				// get a concrete instance of the generator
				generator = resolve(template);

				// configure the generator
				generator.setAssets(bridge.getAssets());
				generator.setTemplate(template);
				generator.setIncludeDirectory(bridge.getIncludeDirectory());
				generator.setLoggingDirectory(bridge.getLoggingDirectory());
				generator.setResourceDirectory(bridge.getResourceDirectory());
				generator.setOutputDirectoy(bridge.getOutputDirectoy());

				// execute the generator
				generator.generate();
			}
		} catch (Exception e) {
			logger.error("Unable to generate epplication", e);
			throw new GenerationException(e);
		}
	}

	/**
	 * Returns the correct implementation of AbstractGenerator
	 * 
	 * @param template
	 * @return
	 * @throws Exception
	 */
	protected AbstractGenerator resolve(Template template) throws Exception {
		// @TODO Configure the correct Generateable based on the information in the Template object.
		// @TODO FIX ME - HARD CODED FOR NOW!!!! Should be configured - maybe use Hivemind here?

		// Class generatorClass = Class.forName("com.tps.filegen.generator.velocity.VelocityApplicationGenerator");
		Class<? extends AbstractGenerator> generatorClass = com.googlecode.archimedes.filegen.generator.freemarker.FreeMarkerApplicationGenerator.class;
		// /////////////////////////////////////

		// Instantiate with a null constructor
		return generatorClass.newInstance();
	}
}
